--- 模块功能：MQTT客户端数据接收处理
-- @author openLuat
-- @module mqtt.mqttInMsg
-- @license MIT
-- @copyright openLuat
-- @release 2018.03.28
module(..., package.seeall)

require "config"
require "nvm"
require "earthquakeWaring"
require "utilsBySelf"
require "earthquakeWaringDril"
require "logGenerator"
require "audio"
require "addCert"

-- 参数配置文件初始化
nvm.init("config.lua", true)

-- nvm参数获取
local fastCount, eqrTopic, topic, enableVerify, regCenter = tonumber(nvm.get(
                                                                         "fastCount")),
                                                            nvm.get(
                                                                "centerConfig")[12],
                                                            nvm.get(
                                                                "centerConfig")[11],
                                                            nvm.get(
                                                                "centerConfig")[21],
                                                            nvm.get("regCenter")
-- 变量初始化
local slen, errInfo, sysTime, action, acountSuspend = string.len, "", "", false,
                                                      0
local setGpio9Fnc = pins.setup(pio.P0_9, 1) -- 静音设置（高电平静音）
local function cbFnc(r)
    if r then if r == 0 then sys.publish("PLAY_FINSH") end end
end
-- 主题是否包含判断
local function isContainEEWTopic(topicEEW)
    local containTopic = false
    local topicListearth = string.split(topic, ",")
    for i = 1, #topicListearth, 1 do
        log.info("topicListearth[1]:",topicListearth[i])
        if topicListearth[i] == topicEEW then containTopic = true end
    end
    return containTopic
end
-- 主题是否包含判断
local function isContainEQRTopic(topicEQR)
    local containTopic = false
    local eqrTopicList = string.split(eqrTopic, ",")
    for i = 1, #eqrTopicList, 1 do
        if eqrTopicList[i] == topicEQR then containTopic = true end
    end
    return containTopic
end
-- 速报播报
local function eqrBroadcast(tjsondataGet)
    local strBroadCast, broadCastCount = "", fastCount
    local msgID, msgType, msgTypeContent, eventID, locName, epiLat, epiLon,
          focdepth, magnitude, oriTime, listDate, listTime
    if tjsondataGet["1"] then
        msgID = tjsondataGet["1"]
        -- strBroadCast = strBroadCast .. "消息ID:" .. msgID
    end
    if tjsondataGet["2"] then
        msgType = tjsondataGet["2"]
        if msgType == "0401" then
            msgTypeContent = "中国地震台网自动测定:"
        elseif msgType == "0402" then
            msgTypeContent = "中国地震台网正式测定:"
        elseif msgType == "0303" then
            msgTypeContent = "速报测试"
        end
        strBroadCast = strBroadCast .. msgTypeContent
    end
    if tjsondataGet["12"] then
        oriTime = tjsondataGet["12"]
        listDate = string.split(string.split(oriTime, " ")[1], "-")
        listTime = string.split(string.split(oriTime, " ")[2], ":")
        strBroadCast = strBroadCast .. ":" .. listDate[2] .. "月" ..
                           listDate[3] .. "日," .. listTime[1] .. "时" ..
                           listTime[2] .. "分在"
    end
    if tjsondataGet["13"] then
        locName = tjsondataGet["13"]
        if msgType == "0401" then
            strBroadCast = strBroadCast .. locName .. "附近"
        elseif msgType == "0402" then
            strBroadCast = strBroadCast .. locName
        elseif msgType == "0303" then
            strBroadCast = strBroadCast .. locName
        end
    end
    if tjsondataGet["15"] then
        epiLat = tjsondataGet["15"]
        strBroadCast = strBroadCast .. "(纬度为" .. epiLat .. "度,经度为"
    end
    if tjsondataGet["14"] then
        epiLon = tjsondataGet["14"]
        strBroadCast = strBroadCast .. epiLon .. "度)发生"
    end
    magnitude = tjsondataGet["17"]
    log.info("magnitude:", magnitude, " msgType == 0401", msgType == "0401")
    if msgType == "0401" then
        strBroadCast = strBroadCast .. magnitude .. "级左右地震，"
    elseif msgType == "0402" then
        strBroadCast = strBroadCast .. magnitude .. "级地震，"
    elseif msgType == "0303" then
        strBroadCast = strBroadCast .. magnitude .. "级地震，"
    end
    focdepth = tjsondataGet["16"]
    log.info("focdepth:", focdepth)
    if msgType == "0401" then
        strBroadCast = strBroadCast .. "最终结果以正式速报为准。"
    elseif msgType == "0402" then
        strBroadCast = strBroadCast .. "震源深度" .. focdepth .. "千米。"
    elseif msgType == "0303" then
        strBroadCast = strBroadCast .. "震源深度" .. focdepth .. "千米。"
    end
    while broadCastCount > 0 do
        setGpio9Fnc(0)
        log.info("strBroadCast:", strBroadCast)
        audio.play(TTS, "TTS", strBroadCast, 7, cbFnc)
        sys.waitUntil("PLAY_FINSH")
        broadCastCount = broadCastCount - 1
        sys.wait(1000)
    end
    setGpio9Fnc(1)
end
--- MQTT客户端数据接收处理
-- @param mqttRClient，MQTT客户端对象
-- @return 处理成功返回true，处理出错返回false
-- @usage mqttInMsg.proc(mqttRClient)
function proc(mqttRClient)
    local result, data, receiveMsg
    while true do
        result, data = mqttRClient:receive(60000, "APP_SOCKET_SEND_DATA")
        errInfo = ""
        log.info("procResult:", result, "procData:", data)
        -- 接收到数据
        if result then
            receiveMsg = data.payload
            errInfo = errInfo .. "[" .. sysTime .. "]" ..
                          "[地震预警信息接收的json报文:]" ..
                          receiveMsg .. "\n"
            log.info("receiveMsg:", receiveMsg, "data.topic:", data.topic)
            sysTime = utilsBySelf.GetSystemTime()
            local tjsondata, resultMqtt, errinfo = json.decode(receiveMsg)
            if isContainEQRTopic(data.topic) then
                if resultMqtt and type(tjsondata) == "table" then
                    if enableVerify == "true" then
                        log.info("进入验签！！！")
                        local verifyResult, returnData
                        verifyResult, returnData =
                            addCert.VerifyMessage(tjsondata)
                        if verifyResult then
                            if fastCount > 0 then
                                sys.taskInit(eqrBroadcast, tjsondata)
                            elseif fastCount == 0 then
                                errInfo =
                                    errInfo .. "[" .. sysTime .. "]" ..
                                        "速报信息播报次数为0" .. "\n"
                            end
                        else
                            sysTime = string.format(
                                          "%04d-%02d-%02d %02d:%02d:%02d",
                                          os.date("*t").year,
                                          os.date("*t").month,
                                          os.date("*t").day, os.date("*t").hour,
                                          os.date("*t").min, os.date("*t").sec)
                            errInfo = errInfo .. "[" .. sysTime .. "]" ..
                                          "[国密验签错误:]" .. returnData ..
                                          "\n"
                        end
                    else
                        if fastCount > 0 then
                            sys.taskInit(eqrBroadcast, tjsondata)
                        elseif fastCount == 0 then
                            errInfo = errInfo .. "[" .. sysTime .. "]" ..
                                          "速报信息播报次数为0" .. "\n"
                        end
                    end

                else
                    errInfo = errInfo .. "[" .. sysTime .. "]" ..
                                  "[速报json报文解析错误:]" .. errinfo ..
                                  "\n"
                end
            elseif isContainEEWTopic(data.topic) then
                if resultMqtt and type(tjsondata) == "table" then
                    if enableVerify == "true" then
                        log.info("进入验签！！！")
                        local verifyResult, returnData
                        verifyResult, returnData =
                            addCert.VerifyMessage(tjsondata)
                        if verifyResult then
                            earthquakeWaring.EarthquakeWarning(receiveMsg,
                                                               tjsondata,
                                                               data.topic)
                        else
                            sysTime = string.format(
                                          "%04d-%02d-%02d %02d:%02d:%02d",
                                          os.date("*t").year,
                                          os.date("*t").month,
                                          os.date("*t").day, os.date("*t").hour,
                                          os.date("*t").min, os.date("*t").sec)
                            errInfo = errInfo .. "[" .. sysTime .. "]" ..
                                          "[国密验签错误:]" .. returnData ..
                                          "\n"
                        end
                    else
                        earthquakeWaring.EarthquakeWarning(receiveMsg,
                                                           tjsondata, data.topic)
                    end
                else
                    errInfo = errInfo .. "[" .. sysTime .. "]" ..
                                  "[地震预警信息json报文解析报错:]" ..
                                  errinfo .. "\n"
                end
            else
                errInfo = errInfo .. "[" .. sysTime .. "]" ..
                              "[B系统主题订阅失败！]" ..
                              "[B系统发布的主题：]" .. data.topic ..
                              "[,订阅的地震预警主题：]" .. topic ..
                              "[,订阅的地震速报主题：]" .. topic ..
                              "\n"
            end
            if slen(errInfo) > 0 then
                logGenerator.generateLogTask(errInfo, "log")
                errInfo = ""
            end
        else
            break
        end
    end
    sysTime = utilsBySelf.GetSystemTime()
    if slen(errInfo) > 0 then
        logGenerator.generateLogTask(errInfo, "log")
        errInfo = ""
    end
    log.info("MQTT INMSG QU TASK CENT  RESULT", tostring(result),
             "MQTT INMSG QU TASK CENT DATA", data)
    return result or data == "timeout" or data == "APP_SOCKET_SEND_DATA"
end
